const app = getApp()
const sudoku = require('../../utils/sudoku.js')
let idx = 0
Page({

  /**
   * 页面的初始数据
   */
  data: {
    is_dark: false,
    user_data: {},
    user_rank: {},
    test: [],
    is_test: [],
    is_test_backups: [],
    input: [],
    answer: [],
    level: 0,
    is_stop: false,
    is_min: '00',
    is_sec: '00',
    is_hour: '00',
    is_input_idx_list: [],
    is_input: false,
    is_answer: [],
    number_list: [...Array.from({
      length: 4
    }, (i, idx) => idx + 1)]
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.setData({
      user_data: app.global_data.user_data,
      is_datk: app.global_data.darkness
    })
    this.getRank()
    this.getTest(0, () => {
      this.setTest()
    })
    this.setTime()
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  /* 获取成绩 */
  getRank() {
    wx.cloud.callFunction({
      name: 'runDb',
      data: {
        type: 'get_detail',
        collection: 'sudoku',
        is_where: {
          "user_openid": this.data.user_data.openid
        },
      },
      complete: res => {
        let detail = res.result.data[0]
        // console.log(detail)
        this.setData({
          user_rank: detail
        })
      }
    })
  },
  /* 启动计时器 */
  setTime() {
    this.data.setInter = setInterval(() => {
      let is_min = this.data.is_min
      let is_hour = this.data.is_hour
      let is_sec = +this.data.is_sec + 1
      if (is_sec < 10) {
        is_sec = "0" + is_sec.toString()
      } else if (is_sec > 59) {
        is_sec = "00"
        is_min = +is_min + 1
        if (is_min < 10) {
          is_min = "0" + is_min.toString()
        } else if (is_min > 59) {
          is_min = "00"
          is_hour = +is_hour + 1
          if (is_hour < 10) {
            is_hour = "0" + is_hour.toString()
          }
        }
      }
      this.setData({
        is_hour,
        is_min,
        is_sec
      })
    }, 1000)
  },
  /* 清除计时器 */
  clearTime() {
    clearInterval(this.data.setInter)
  },
  /* 获取题目 */
  getTest(level, cb) {
    let base
    let length_idx
    switch (level) {
      case 0:
        base = 2
        length_idx = 4
        break
      case 1:
      case 2:
        base = 3
        length_idx = 9
        break
      default:
        break
    }
    let test = sudoku.makeDigits(base, length_idx)
    if (!test) {
      if (idx < 1000) {
        idx++
        this.getTest(level, cb)
      } else {
        wx.showToast({
          title: '题目生成错误,请刷想重试',
          icon: "none",
        })
      }
    } else {
      wx.setStorageSync('test', test)
      this.setData({
        test: wx.getStorageSync('test')
      })
      cb()
    }
  },
  /* 设置题目 */
  setTest() {
    let is_test = wx.getStorageSync('test')
    let is_length = is_test.length
    switch (this.data.level) {
      case 0:
        is_test.forEach(i => {
          let remove_idx = this.randomLength(3) + 1
          let random_index_list = this.randomIndex(remove_idx, 4)
          for (let j = 0; j < random_index_list.length; j++) {
            i[random_index_list[j]] = ''
          }
        })
        break
      case 1:
        is_test.forEach(i => {
          let remove_idx = this.randomLength(3) + 3
          let random_index_list = this.randomIndex(remove_idx, 9)
          for (let j = 0; j < random_index_list.length; j++) {
            i[random_index_list[j]] = ''
          }
        })
        break
      case 2:
        is_test.forEach(i => {
          let remove_idx = this.randomLength(3) + 5
          let random_index_list = this.randomIndex(remove_idx, 9)
          for (let j = 0; j < random_index_list.length; j++) {
            i[random_index_list[j]] = ''
          }
        })
        break
      default:
        break
    }
    // console.log(is_test)
    let list = this.setInputItem(is_test)
    // console.log(list)
    wx.setStorageSync('is_test', list)
    this.setData({
      is_test: list,
    })
  },
  /* 设置题目空格数 */
  randomLength(i) {
    return Math.floor(Math.random() * i)
  },
  /* 清除项下标 */
  randomIndex(number, length) {
    let index_array = [...Array.from({
      length: length
    }, (i, idx) => idx)]
    let out_index = []
    while (out_index.length < number) {
      var temp = (Math.random() * index_array.length) >> 0;
      out_index.push(index_array[temp])
    }
    return out_index
  },
  /* 设置输入属性 */
  setInputItem(arr) {
    let list = arr.map((i, i_idx) => {
      return i = i.map((j, j_idx) => {
        return j = {
          number: j,
          is_input: j ? false : true,
          idx: i_idx.toString() + j_idx.toString(),
          is_active: false,
          is_link: false,
          is_same: false,
          is_wrong: false
        }
      })
    })
    return list
  },
  /* 玩法等级 */
  changeLevel(e) {
    let {
      idx
    } = e.currentTarget.dataset
    idx = +idx
    if (idx > 0) {
      this.setData({
        number_list: [...Array.from({
          length: 9
        }, (i, idx) => idx + 1)]
      })
    } else {
      this.setData({
        number_list: [...Array.from({
          length: 4
        }, (i, idx) => idx + 1)]
      })
    }
    this.setData({
      level: idx
    })
    this.resetTest()
    this.getTest(this.data.level, () => {
      this.setTest()
    })
  },
  /* 点击暂停 */
  clickTime() {
    this.setData({
      is_stop: !this.data.is_stop
    })
    if (this.data.is_stop) {
      this.clearTime()
    } else {
      this.setTime()
    }
  },
  /* 刷新题目 */
  resetTest() {
    this.setData({
      test: [],
      input: [],
      answer: [],
      is_stop: false,
      is_min: '00',
      is_sec: '00',
      is_hour: '00'
    })
    this.clearTime()
    this.setTime()
  },
  /* 选中空格 */
  clickItem(e) {
    if (this.data.is_stop) {
      wx.vibrateLong({})
      return
    }
    let {
      idx,
      input
    } = e.currentTarget.dataset
    let is_input = input
    // console.log(idx, is_input)
    this.resetIdx(() => {
      let idx_list = this.getIdx(idx)
      this.setActive(idx_list, is_input)
      this.setSame(idx_list)
      this.setLine(idx_list)
    })
  },
  /* 设置相同 */
  setSame(idx) {
    let idx_list = idx
    let is_test = this.data.is_test
    let is_number = is_test[idx_list[0]][idx_list[1]].number
    if (is_number) {
      is_test.forEach(i => {
        i.forEach(j => {
          if (j.number == is_number) {
            j.is_same = true
          }
        })
      })
      this.setData({
        is_test
      })
    }
  },
  /* 设置横竖 */
  setLine(idx) {
    let idx_list = idx
    let is_test = this.data.is_test
    is_test.forEach(i => {
      i[idx_list[1]].is_link = true
    })
    is_test[idx_list[0]].forEach(i => {
      i.is_link = true
    })
    this.setData({
      is_test
    })
  },
  /* 设置选中 */
  setActive(idx, is_input) {
    let idx_list = idx
    let is_test = this.data.is_test
    if (is_test[idx_list[0]][idx_list[1]].is_input) {
      is_test[idx_list[0]][idx_list[1]].is_active = true
      this.setData({
        is_input_idx_list: idx_list,
        is_input,
        is_test
      })
    }
  },
  /* 重置属性 */
  resetIdx(cb) {
    let is_test = this.data.is_test
    is_test.forEach(i => {
      i.forEach(j => {
        j.is_active = false
        j.is_link = false
        j.is_same = false
        j.is_wrong = false
      })
    })
    this.setData({
      is_test
    })
    cb()
  },
  /* 操作选中 */
  handleItem(e) {
    if (this.data.is_stop) {
      wx.vibrateLong({})
      return
    }
    let {
      idx
    } = e.currentTarget.dataset
    idx = +idx
    let idx_list = this.data.is_input_idx_list
    let is_test = this.data.is_test
    if (this.data.is_input) {
      if (idx < 10) {
        is_test[idx_list[0]][idx_list[1]].number = idx
        this.setData({
          is_test
        })
        let is_all = is_test.map(i => {
          return i.map(j => {
            let is_number = j.number
            if (!is_number) return false
            return true
          })
        })
        is_all = is_all.toString().split(",")
        if (!is_all.includes("false")) {
          this.checkInput()
        }
      } else if (idx === 13) {
        is_test[idx_list[0]][idx_list[1]].number = ''
        this.setData({
          is_test
        })
      }
    }
    switch (idx) {
      case 11:
        this.resetIdx(() => {})
        break
      case 12:
        this.checkInput()
        break
      case 14:
        this.resetIsTest()
        break
      default:
        break
    }
  },
  /* 获取选中id */
  getIdx(idx) {
    let a, b
    let idx_list = idx.split("")
    a = +idx_list[0]
    b = +idx_list[1]
    return [a, b]
  },
  /* 重置输入 */
  resetIsTest() {
    this.setData({
      is_test: wx.getStorageSync('is_test')
    })
  },
  /* 检查输入 */
  checkInput() {
    let is_test = this.data.is_test
    let is_length = is_test.length
    let row_list = []
    let col_list = []
    let row_count = 0
    let col_count = 0
    let area_count = 0
    let i = 0
    let idx_base = 3
    if (this.data.level === 0) {
      idx_base = 2
    }
    for (i = 0; i < is_length; i++) {
      row_list = is_test[i].map(j => {
        return j.number
      })
      col_list = is_test.map(j => {
        return j[i].number
      })
      let is_none_row = this.isNone(row_list)
      let is_none_col = this.isNone(col_list)
      let is_repeat_row = this.isRepeat(row_list)
      let is_repeat_col = this.isRepeat(col_list)
      let is_all_row = this.isAll(row_list)
      let is_all_col = this.isAll(col_list)
      if (is_none_row || is_none_col) {
        is_test.forEach(i => {
          i.forEach(j => {
            let is_number = j.number
            if (!is_number) {
              j.is_wrong = true
            }
          })
        })
        this.setData({
          is_test
        })
      } else if (!is_none_row && !is_none_col) {
        if (!is_repeat_row) {
          this.setTestWrongRow(i)
        } else {
          if (!is_all_row) {
            this.setTestWrongRow(i)
          } else {
            row_count++
          }
        }
        if (!is_repeat_col) {
          this.setTestWrongCol(i)
        } else {
          if (!is_all_col) {
            this.setTestWrongCol(i)
          } else {
            col_count++
          }
        }
      }
      for (let k = 0; k < is_length; k++) {
        if (i % idx_base === 0 && k % idx_base === 0) {
          let area_list = []
          for (let l = 0; l < idx_base; l++) {
            for (let m = 0; m < idx_base; m++) {
              area_list.push(is_test[i + m][l + k].number)
            }
          }
          let is_area_repeat = this.isRepeat(area_list)
          let is_area_all = this.isAll(area_list)
          if (!is_area_repeat) {
            // console.log(k, i)
            this.setTestWrongArea(k, i)
          } else {
            if (!is_area_all) {
              this.setTestWrongArea(k, i)
            } else {
              area_count++
            }
          }
        }
      }
    }
    if (row_count === 4 && col_count === 4 && area_count === 4) {
      wx.showToast({
        title: '完成!',
      })
      this.getScore()
    }
  },
  /* 设置行错误 */
  setTestWrongRow(idx) {
    let is_test = this.data.is_test
    is_test[idx].forEach(j => {
      let is_input = j.is_input
      if (is_input) {
        j.is_wrong = true
      }
    })
    this.setData({
      is_test
    })
  },
  /* 设置列错误 */
  setTestWrongCol(idx) {
    let is_test = this.data.is_test
    is_test.forEach(j => {
      let is_input = j[idx].is_input
      if (is_input) {
        j[idx].is_wrong = true
      }
    })
    this.setData({
      is_test
    })
  },
  /* 设置宫错误 */
  setTestWrongArea(y, x) {
    let idx_base = 3
    if (this.data.level === 0) {
      idx_base = 2
    }
    let is_test = this.data.is_test
    for (let l = 0; l < idx_base; l++) {
      for (let m = 0; m < idx_base; m++) {
        let is_input = is_test[x + m][y + l].is_input
        if (is_input) {
          is_test[x + m][y + l].is_wrong = true
        }
      }
    }
    this.setData({
      is_test
    })
  },
  /* 判断是否为空 */
  isNone(arr) {
    for (let i in arr) {
      if (!i)
        return true
    }
    return false
  },
  /* 判断一个数组是否有重复的值 */
  isRepeat(arr) {
    let hash = {}
    for (let i in arr) {
      if (!hash[arr[i]])
        return true
    }
    return false
  },
  /* 判断是否合法 */
  isAll(arr) {
    let is_sum = 45
    let is_length = arr.length
    if (this.data.level === 0) {
      is_sum = 10
    }
    var sum = 0
    for (var i = 0; i < is_length; i++) {
      sum += arr[i]
    }
    return sum == is_sum ? true : false
  },
  /* 上传成绩 */
  getScore() {
    this.clearTime()
    let that = this
    let is_time = this.data.is_hour + ":" + this.data.is_min + ":" + this.data.is_sec
    let data = {
      user_openid: this.data.user_data.openid,
      level: this.data.level,
      score_time: is_time,
      update_time: app.dayjs().valueOf()
    }
    // console.log(data)
    if (this.data.user_rank && this.data.level === this.data.user_rank.level) {
      if (data.score < this.data.user_rank.score) {
        wx.showToast({
          title: '成绩未提升,请努力哦!',
          icon: 'none'
        })
        wx.redirectTo({
          url: '/pages/minigame_list/minigame_list',
        })
      } else if (data.score == this.data.user_rank.score && data.score_time > this.data.user_rank.score_time) {
        wx.showToast({
          title: '成绩未提升,请努力哦!',
          icon: 'none'
        })
        wx.redirectTo({
          url: '/pages/minigame_list/minigame_list',
        })
      } else {
        wx.cloud.callFunction({
          name: "runDb", //云函数名
          data: {
            type: 'update_detail', //指定操作类型
            collection: 'sudoku', //修改的集合名称
            is_where: {
              "user_openid": that.data.user_data.openid
            },
            data //更新的数据
          },
          success: res => {
            wx.showToast({
              title: '更新得分成功',
              duration: 500,
              success: res => {
                wx.redirectTo({
                  url: '/pages/minigame_list/minigame_list'
                })
              }
            })
          },
          fail: err => {
            console.error('更新得分失败', err)
          }
        })
      }
    } else {
      wx.cloud.callFunction({
        name: "runDb", //云函数名
        data: {
          type: 'insert', //指定操作类型
          collection: 'sudoku', //修改的集合名称
          data //更新的数据
        },
        success: res => {
          wx.showToast({
            title: '上传得分成功',
            duration: 500,
            success: res => {
              wx.redirectTo({
                url: '/pages/minigame_list/minigame_list'
              })
            }
          })
        },
        fail: err => {
          console.error('上传得分失败', err)
        }
      })
    }
  }
})